package com.liuyk.commonlib.web.bridge;

import java.lang.ref.SoftReference;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Bridge分发基类
 * <p>
 * Created by liuyakui on 2020/7/6
 */
public abstract class BaseBridge {

    private Map<String, HandlerMethod> bridges;

    public BaseBridge() {
        bridges = new HashMap<>();
        onCreate();
    }

    public abstract void onCreate();

    public abstract String getBridgeName();

    public String handle(String action, boolean isSync, String extra, String callbackFunction, String params, BasisView basisView) {
        try {
            HandlerMethod hm = getBridges().get(action);
            if (hm != null) {
                if (hm.method == null || hm.method.get() == null) {
                    Method md = getClazz().getMethod(hm.name, String.class, boolean.class,
                            String.class, String.class, String.class, BasisView.class);
                    hm.method = new SoftReference<>(md);
                }
                return (String) hm.method.get().invoke(null, action, isSync, extra,
                        callbackFunction, params, basisView);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public Method getMethod() {
        try {
            return getClazz().getMethod("handle", String.class,
                    boolean.class, String.class, String.class, String.class, BasisView.class);
        } catch (Exception e) {
            return null;
        }
    }

    public void initBridgeMethod(Object o) {
        final Class<?> aClass = o.getClass();
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            method.setAccessible(true);//去掉安全检查
            final BridgeMethod annotation = method.getAnnotation(BridgeMethod.class);
            if (annotation == null) {
                continue;
            }
            try {
//                Method m = aClass.getMethod(annotation.methodName());
                getBridges().put(annotation.methodName(), new HandlerMethod(annotation.methodName(), null));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public abstract Class<?> getClazz();

    public Map<String, HandlerMethod> getBridges() {
        return bridges;
    }
}
